<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
    <title>Page not found &middot; GitHub Pages</title>
    <style>
        #c {
            position: fixed;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            display: block;
            z-index: -1;
            /* background-color: red; */
        }

        .diagram {
            display: inline-block;
            width: 5em;
            height: 3em;
            border: 1px solid black;
        }

        .left {
            float: left;
            margin-right: .25em;
        }

        .right {
            float: right;
            margin-left: .25em;
        }
    </style>
</head>

<script type="importmap">
    {
        "imports": {
          "three": "../three.js-r151/build/three.module.js",
          "three/addons/": "../three.js-r151/examples/jsm/"
        }
      }
</script>

<body>
    <canvas id="c"></canvas>
    <p>
        <span id="box" class="diagram left"></span>
        看不懂，<a href="https://threejs.org/manual/#zh/multiple-scenes">多个画布，多个场景</a>
    </p>
    <p>
        <span id="pyramid" class="diagram right"></span>
        When I was a kid I dreamed of going on an expedition inside a pyramid
        and finding a undiscovered tomb full of mummies and treasure.
        <br/>
        大概流程：<br/>
        <li>1. 公用一个render，dom </li>
        <li>2. 各自的camera、scene，可以共有材质，节省空间 </li>
        
    </p>

</body>

<script type="module">
    import * as THREE from 'three';
    import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

    // 生成场景、相机
    function makeScene(elem) {
        const scene = new THREE.Scene();

        const fov = 45;
        const aspect = 2;  // the canvas default
        const near = 0.1;
        const far = 5;
        const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
        camera.position.z = 2;
        camera.position.set(0, 1, 2);
        camera.lookAt(0, 0, 0);

        {
            const color = 0xFFFFFF;
            const intensity = 1;
            const light = new THREE.DirectionalLight(color, intensity);
            light.position.set(-1, 2, 4);
            scene.add(light);
        }

        return { scene, camera, elem };
    }

    // 场景对象：{ scene, camera, elem, mesh }
    function setupScene1() {
        const sceneInfo = makeScene(document.querySelector('#box'));
        const geometry = new THREE.BoxGeometry(1, 1, 1);
        const material = new THREE.MeshPhongMaterial({ color: 'red' });
        const mesh = new THREE.Mesh(geometry, material);
        sceneInfo.scene.add(mesh);
        sceneInfo.mesh = mesh;
        return sceneInfo;
    }

    function setupScene2() {
        const sceneInfo = makeScene(document.querySelector('#pyramid'));
        const radius = .8;
        const widthSegments = 4;
        const heightSegments = 2;
        const geometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments);
        const material = new THREE.MeshPhongMaterial({
            color: 'blue',
            flatShading: true,
        });
        const mesh = new THREE.Mesh(geometry, material);
        sceneInfo.scene.add(mesh);
        sceneInfo.mesh = mesh;
        return sceneInfo;
    }


    // 视图信息获取函数如下： 看不懂。。。
    function renderSceneInfo(sceneInfo) {
        const { scene, camera, elem } = sceneInfo;

        // get the viewport relative position of this element
        const { left, right, top, bottom, width, height } =
            elem.getBoundingClientRect();

        const isOffscreen =
            bottom < 0 ||
            top > renderer.domElement.clientHeight ||
            right < 0 ||
            left > renderer.domElement.clientWidth;

        if (isOffscreen) {
            return;
        }

        camera.aspect = width / height;
        camera.updateProjectionMatrix();

        // console.log("bottom", bottom);
        // const positiveYUpBottom = canvasRect.height - bottom;
        const positiveYUpBottom = 100;

        renderer.setScissor(left, positiveYUpBottom, width, height);
        renderer.setViewport(left, positiveYUpBottom, width, height);

        renderer.render(scene, camera);
    }

    function resizeRendererToDisplaySize(renderer) {
        const canvas = renderer.domElement;
        const width = canvas.clientWidth;
        const height = canvas.clientHeight;
        const needResize = canvas.width !== width || canvas.height !== height;
        if (needResize) {
            renderer.setSize(width, height, false);
        }
        return needResize;
    }

    // 视图渲染函数如下：
    function render(time) {
        time *= 0.001;

        resizeRendererToDisplaySize(renderer);

        renderer.setScissorTest(false);
        renderer.clear(true, true);
        renderer.setScissorTest(true);

        sceneInfo1.mesh.rotation.y = time * .1;
        sceneInfo2.mesh.rotation.y = time * .1;

        renderSceneInfo(sceneInfo1);
        renderSceneInfo(sceneInfo2);

        requestAnimationFrame(render);
    }

    // 1. 创建共有的渲染器Render，添加共有的画布canvas
    const canvas = document.querySelector('#c');
    const renderer = new THREE.WebGLRenderer({
        canvas,
        alpha: true,
        antialias: true
    });

    // 2. 生成各自的场景对象
    const sceneInfo1 = setupScene1();
    const sceneInfo2 = setupScene2();
    console.log("sceneInfo1", sceneInfo1);
    console.log("sceneInfo2", sceneInfo2);

    // 3. render
    render();
</script>

</html>